package com.arpa.ntocc.common.security.aspect;

import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.security.annotation.NoReSubmit;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 禁止重复提交
 */
@Order(-1)
@Component
@Aspect
@Log4j2
public class NoReSubmitAop {

    @Resource
    private RedissonClient redissonClient;

    @Around("@annotation(noReSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, NoReSubmit noReSubmit) throws Throwable {
        RLock lock = null;
        try {
            if (noReSubmit != null) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String uri = request.getRequestURI();
                String key = noReSubmit.keyPrefix() + "_" + UserUtil.getCode() + "_" + uri;
                lock = redissonClient.getLock(key);
                if (!lock.tryLock()) {
                    lock = null;
                    throw new RuntimeException(noReSubmit.msg());
                }
            }
            return joinPoint.proceed();
        } catch (Exception e) {
            log.error("禁止重复提交异常：", e);
            return Result.error(501, e.getMessage());
        } finally {
            if (null != lock) {
                lock.unlock();
            }
        }
    }

}

